/**
 * A GUI component that can render a Drawing.
 * 
 * @author Giuseppe Mendola (giuseppe.mendola@usi.ch); Gregory Banfi (gregory.banfi@usi.ch)
 */

package ch.usi.inf.pf2.gui;

import javax.swing.JComponent;

import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.Color;
import javax.swing.ToolTipManager;

import ch.usi.inf.pf2.Component;
import ch.usi.inf.pf2.Wire;
import ch.usi.inf.pf2.Gates.And;
import ch.usi.inf.pf2.Gates.Not;
import ch.usi.inf.pf2.Gates.Or;
import ch.usi.inf.pf2.puts.Input;
import ch.usi.inf.pf2.puts.Output;

@SuppressWarnings({ "serial", "unused" })
public final class DrawingArea extends JComponent {

	private final Model model;
	private Tool currentTool;
	private Tool[] tools;

	public DrawingArea(final Model model) {
		this.model = model;

		tools = new Tool[] { new SelectionTool(model),
				new DragAndDropTool(model), new ArrayListInputTool(model),
				new AndCreationTool(model), new OrCreationTool(model),
				new NotCreationTool(model), new WireCreationTool(model),
				new InputCreationTool(model), new OutputCreationTool(model), };
		setCurrentTool(tools[0]);

		ToolTipManager.sharedInstance().registerComponent(this);

		// register listeners
		Model.getDrawing().addDrawingListener(new DrawingListener() {
			@Override
			public void drawingChanged() {
				repaint();
			}
		});
		Model.getSelection().addSelectionListener(new SelectionListener() {
			@Override
			public void selectionChanged() {
				repaint();
			}
		});
	}

	/**
	 * This method returns the Tool[] field.
	 * 
	 * @return tools The Tool[] field.
	 */
	public Tool[] getTools() {
		return tools;
	}

	/**
	 * This method returns the currentTool field.
	 * 
	 * @return currentTool The currentTool field.
	 */
	public Tool getCurrentTool() {
		return currentTool;
	}

	/**
	 * This method set the currentTool field.
	 * 
	 * @param tool
	 *            The tool we want to set as currentTool field.
	 */
	public void setCurrentTool(final Tool tool) {
		if (currentTool != null) {
			removeMouseListener(currentTool);
			removeMouseMotionListener(currentTool);
			removeKeyListener(currentTool);
		}
		this.currentTool = tool;
		if (currentTool != null) {
			addMouseListener(currentTool);
			addMouseMotionListener(currentTool);
			addKeyListener(currentTool);
		}
	}

	@Override
	public String getToolTipText(final MouseEvent ev) {
		final int x = ev.getX();
		final int y = ev.getY();
		final Component component = Model.getDrawing().findComponentAt(x, y);
		return component == null ? null : "<html><b>"
				+ component.getClass().getName() + "</b><br>" + component;
	}

	@Override
	public void paintComponent(final Graphics g) {
		// System.out.println("paintComponent");
		g.setColor(Color.WHITE);
		g.fillRect(0, 0, getWidth(), getHeight());

		g.setColor(Color.LIGHT_GRAY);
		for (final Component component : Model.getDrawing()) {
			// System.out.println(component);
				if (!(component == null)){
				component.draw(g, Color.LIGHT_GRAY);
				}
			}

		for (final Component component : Model.getSelection()) {
			
			if (!(component == null)){
				//g.setColor(Color.BLUE);
				component.draw(g, Color.BLUE);
			}
		}
			
		g.setColor(Color.BLACK);
		g.drawLine(0, 0, getWidth(), getHeight());
		g.drawLine(0, getHeight(), getWidth(), 0);
	}	

}
